/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package main;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.text.DecimalFormat;
import java.util.ArrayList;
import java.util.Random;
import players.IntPlayer;
import players.Player;
import players.RandPlayer;

/**
 *
 * @author theworldiwant
 */
public class Lucky9 {

    private Card c;
    private int pThreshold;
    private int numRounds;
    private ArrayList<Player> players;
    private int[] winners;
    //for round table
    private Object[][] roundData, finalTable;           //lgay mo sa gui :)
    private int[][] winTable;
    private ArrayList<Object[][]> roundTables;
    private int[] deckSize;                                                //ala lng for deck size
    
    public Lucky9(int pThreshold, int numRounds) {
        //getInput();
        this.pThreshold = pThreshold;
        this.numRounds = numRounds;
       deckSize=new int[numRounds];
        init();
        shufflePlayers();                       //assuming once lng mgshushuffle ng players
        for (int i = 0; i < numRounds; i++) {
            
            if (c.getDeckSize() < 12) {
                c.initCards();
            }
            distribCard();
            initRoundTable1();
            //System.out.println("after ask for third");
            for (int j = 0; j < 4; j++) {
                if (players.get(j).getType().equals("Intelligent")) {

                    IntPlayer ip = (IntPlayer) players.get(j);
                    if (ip.isAskForThird(c)) {
                        getThirdCard(j);
                        players.get(j).setAskForThird(true);
                    }
                } else if (players.get(j).getType().equals("Random")) {
                    RandPlayer rp = (RandPlayer) players.get(j);
                    if (rp.isgetCard()) {
                        getThirdCard(j);
                        players.get(j).setAskForThird(true);
                    }
                } else if (players.get(j).isAskForThird()) {

                    getThirdCard(j);
                    players.get(j).setAskForThird(true);
                }
            }


            sortWinner();
            for (int m = 0; m < 4; m++) {
                players.get(m).setPlace(-1);
            }
            initRoundTable2();
            roundTables.add(roundData);
            countWinner();
            winners = new int[4];
            shufflePlayers();
            deckSize[i]=c.getDeckSize();
        }
        initFinalTable();
        traverse();

        /*
         * IntPlayer p = (IntPlayer)players.get(2);
         * System.out.println(p.isAskForThird(c));
         */
    }

    public void getInput() {
        InputStreamReader iStream = new InputStreamReader(System.in);
        BufferedReader bufRead = new BufferedReader(iStream);
        boolean finishInput = true;

        while (finishInput) {
            try {
                System.out.println("Enter P:");
                pThreshold = Integer.parseInt(bufRead.readLine());

                System.out.println("Enter Number of Rounds:");
                numRounds = Integer.parseInt(bufRead.readLine());

                if (numRounds < 1 || pThreshold < 1) {
                    System.out.println("Error: Input should be greater than 0");
                } else {
                    finishInput = false;
                }

            } catch (NumberFormatException numErr) {
                System.out.println("Error:  Input is not a number");
            } catch (IOException err) {
                System.out.println("Input Error");
            }
        }
    }

    public void init() {

        c = new Card();
        winners = new int[4];
        winTable = new int[4][4];
        roundTables = new ArrayList<Object[][]>();
        c.initCards();
        c.traverse();
    }

    public void initPlayers() {
        players = new ArrayList<Player>();


        Player a = new Player();
        Player s = new Player();
        IntPlayer inP = new IntPlayer(pThreshold);
        RandPlayer r = new RandPlayer();

        a.setType("Agressive");
        a.setScoreThreshold(7);
        s.setType("Safe");
        s.setScoreThreshold(5);
        inP.setType("Intelligent");
        inP.setP(pThreshold);
        r.setType("Random");

        players.add(s);
        players.add(a);
        players.add(r);
        players.add(inP);
    }

    public void shufflePlayers() {
        Random rand = new Random();
        initPlayers();
        for (Player p : players) {
            p.setPosition(-1);
        }

        int k = rand.nextInt(4), i = 0;
        for (Player p : players) {
            while (isThere(k)) {
                k = rand.nextInt(4);
            }
            i++;
            p.setPosition(k);
        }

    }

    public void distribCard() {
        for (int a = 0; a < 4; a++) {
            for (Player p : players) {
                if (p.getPosition() == a) {
                    p.addCard(c.getACard()+1);
                    c.removeFromDeck();
                    p.addCard(c.getACard()+1);
                    c.removeFromDeck();
                }
            }
        }
    }

    public void getThirdCard(int p) {    //index of player
        players.get(p).addCard(c.getACard()+1);
        //players.get(p).setAskForThird(true);
        //System.out.println("THIRD CARD:" + players.get(p).getAskForThird());
        c.removeFromDeck();
    }

    private Boolean isThere(int k) {
        for (Player p : players) {
            if (p.getPosition() == k) {
                return true;
            }
        }
        return false;
    }

    private void traverse() {/*
         * for(Player s: players){ for(int x: s.getCards() )
         * System.out.print(s.getPosition()+" " +x); System.out.println(" ");
        }
         */


        int m = 0;
        for (Object[][] round : roundTables) {
            System.out.println("*------------- Round " + (m + 1) + "---------------------------------------*");
            for (int i = 0; i < 4; i++) {
                for (int j = 0; j < 6; j++) {
                    System.out.print(round[i][j] + "     ");
                }
                System.out.println("");
            }
            m++;
        }
        for (int i = 0; i < 4; i++) {
            System.out.println("Player" + (i + 1));
            for (int j = 0; j < 5; j++) {
                System.out.print(finalTable[i][j] + "    ");
            }
            System.out.println();
        }

    }

    private void sortWinner() {
        boolean once=false;
        int[] x = new int[4];
        int temp = 0;
        for (int i = 0; i < 4; i++) {
            x[i] = players.get(i).getScore();
        }

        for (int i = 0; i < 4; i++) {                                 //sort
            for (int j = 0; j < 4; j++) {
                if (x[i] > x[j]) {
                    temp = x[j];
                    x[j] = x[i];
                    x[i] = temp;
                }
            }

        }
        for(int i=0; i<3; i++){                                 //removes the nonsense same score
            if(x[i]==x[i+1]){
                if(i==0){
                    x[1]=x[2];
                    x[2] = x[3];
                }
                if(i==1)
                    x[2] = x[3];
            }
        }
            
        for (int i = 0; i < 4; i++) {                              //determine the position
            for (int j = 0; j < 4; j++) {
              if (players.get(j).getScore() == x[i] && players.get(j).getPlace() == -1) {
                    winners[j] = i+1;
                    players.get(j).setPlace(i); 
              }
            }
        }
         
    }

    public void initRoundTable1() {                                                      //before the askforthird
        roundData = new Object[4][6];

        for (int i = 0; i < 4; i++) {
            roundData[i][0] = players.get(i).getPosition();
            roundData[i][1] = players.get(i).getType();

            roundData[i][2] = "";
            for (int m = 0; m < 2; m++) {
                if (m == 1) {
                    roundData[i][2] += " +";
                }
                roundData[i][2] = roundData[i][2] + "" + players.get(i).getCards().get(m);
            }
            roundData[i][2] += " = " + players.get(i).getScore();

        }
    }

    public void initRoundTable2() {                                        //after askForThird
        int m = 0;
        for (int i = 0; i < 4; i++) {
            roundData[i][3] = players.get(i).getAskForThird();
            roundData[i][4] = "";
            for (m = 0; m < 2; m++) {
                if (m == 1) {
                    roundData[i][4] += " +";
                }
                roundData[i][4] = roundData[i][4] + "" + players.get(i).getCards().get(m);

            }
            if (players.get(i).getCards().size() == 3) {
                roundData[i][4] = roundData[i][4] + " + " + players.get(i).getCards().get(2);
            }
            roundData[i][4] += " = " + players.get(i).getScore();
            roundData[i][5] = winners[i];

        }
    }

    public void countWinner() {
        for (int i = 0; i < 4; i++) {
            switch (winners[i]) {
                case 1:
                    winTable[i][0] += 1;
                    break;
                case 2:
                    winTable[i][1] += 1;
                    break;
                case 3:
                    winTable[i][2] += 1;
                    break;
                case 4:
                    winTable[i][3] += 1;
            }
        }
    }

    public void initFinalTable() {
        finalTable = new Object[4][5];
        DecimalFormat df= new DecimalFormat("#.##");
        for (int i = 0; i < 4; i++) {
            finalTable[i][0] = players.get(i).getType();
            finalTable[i][1] = winTable[i][0]+ " ( "+(df.format((double)winTable[i][0]/(double)numRounds))+" % )";
            finalTable[i][2] = winTable[i][1]+" ( "+(df.format((double)winTable[i][1]/(double)numRounds))+" % )";
            finalTable[i][3] = winTable[i][2]+ " ( "+(df.format((double)winTable[i][2]/(double)numRounds))+" % )";
            finalTable[i][4] = winTable[i][3]+ " ( "+(df.format((double)winTable[i][3]/(double)numRounds))+" % )";
        }
    }

    public Object[][] getFinalTable() {
        return finalTable;
    }

    public ArrayList<Object[][]> getRoundTable() {
        return roundTables;
    }

    /**
     * @return the deckSize
     */
    public int[] getDeckSize() {
        return deckSize;
    }
}
